package com.unitd.base.frame.plugin.db.datasource.context;

import com.unitd.base.frame.plugin.db.datasource.factory.AtomikosFactory;
import com.unitd.base.frame.plugin.db.datasource.factory.DataSourceFactory;
import com.unitd.base.frame.plugin.db.datasource.properties.DruidProperties;

import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 数据源的上下文容器(单例)
 *
 * @author Hudan
 * @version 1.0
 * @filename DataSourceContext.java
 * @copyright www.unitd.com
 * @date 2020-06-28
 */
public class DataSourceContext {

    /** 主数据源数据库类型 */
    public static final String MASTER_DATASOURCE_TYPE = "MYSQL";
    /** 主数据源名称 */
    public static final String MASTER_DATASOURCE_NAME = "master";
    /** 数据源容器 */
    private static Map<String, DataSource> DATA_SOURCES = new ConcurrentHashMap<>();
    /** 数据源的配置容器 */
    private static Map<String, DruidProperties> DATA_SOURCES_CONF = new ConcurrentHashMap<>();

    /**
     * 初始化主数据源,更新该数据源信息为当前应用配置的主数据员
     *
     * @param masterDataSourceProperties 主数据源配置信息
     * @param dataSourcePrimary          主数据源
     */
    public static void initDataSource(DruidProperties masterDataSourceProperties, DataSource dataSourcePrimary) {

        // 清空数据库中的主数据源信息
        new DataSourceFactory(masterDataSourceProperties).deleteMasterDatabaseInfo();

        // 初始化主数据源信息
        new DataSourceFactory(masterDataSourceProperties).createMasterDatabaseInfo();

        // 从数据库中获取所有的数据源信息
        DataSourceFactory dataSourceFactory = new DataSourceFactory(masterDataSourceProperties);
        Map<String, DruidProperties> allDataBaseInfo = dataSourceFactory.getAllDataBaseInfo();

        // 赋给全局变量
        DATA_SOURCES_CONF = allDataBaseInfo;

        // 根据数据源信息初始化所有的DataSource
        for (Map.Entry<String, DruidProperties> entry : allDataBaseInfo.entrySet()) {

            String dbName = entry.getKey();
            DruidProperties druidProperties = entry.getValue();

            // 如果是主数据源，不用初始化第二遍，如果是其他数据源就通过property初始化
            if (dbName.equalsIgnoreCase(MASTER_DATASOURCE_NAME)) {
                DATA_SOURCES_CONF.put(dbName, druidProperties);
                DATA_SOURCES.put(dbName, dataSourcePrimary);
            } else {
                DataSource dataSource = createDataSource(dbName, druidProperties);
                DATA_SOURCES.put(dbName, dataSource);
            }
        }
    }

    /**
     * 新增动态数据源
     *
     * @param dbName     数据源名称
     * @param dataSource 数据源参数信息
     */
    public static void addDataSource(String dbName, DataSource dataSource) {
        DATA_SOURCES.put(dbName, dataSource);
    }

    /**
     * 获取动态数据源
     */
    public static Map<String, DataSource> getDataSources() {
        return DATA_SOURCES;
    }

    /**
     * 获取数据源的配置
     */
    public static Map<String, DruidProperties> getDataSourcesConfs() {
        return DATA_SOURCES_CONF;
    }

    /**
     * 使用动态数据源模板,创建动态数据源
     *
     * @param dataSourceName  动态数据源名称
     * @param druidProperties 动态数据源Druid数据库连接池参数
     * @return 动态数据源
     */
    public static DataSource createDataSource(String dataSourceName, DruidProperties druidProperties) {

        // 添加到全局配置里
        DATA_SOURCES_CONF.put(dataSourceName, druidProperties);

        return AtomikosFactory.create(dataSourceName, druidProperties);
    }
}